/////////////////////////////////////////////////////////////////////////////
// Name:        tts_speechsettingspanel.cpp
// Purpose:     
// Author:      Julian Smart
// Modified by: 
// Created:     19/02/2009 07:08:51
// RCS-ID:      
// Copyright:   (c) Anthemion Software Limited
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"
#include "wx/filename.h"

////@begin includes
////@end includes

#include "tts/tts_speechsettingspanel.h"
#include "tts/tts_custompronunciationdialog.h"

////@begin XPM images
////@end XPM images

/*
 * wxTTSSpeechSettingsPanel type definition
 */

IMPLEMENT_DYNAMIC_CLASS( wxTTSSpeechSettingsPanel, wxPanel )


/*
 * wxTTSSpeechSettingsPanel event table definition
 */

BEGIN_EVENT_TABLE( wxTTSSpeechSettingsPanel, wxPanel )

////@begin wxTTSSpeechSettingsPanel event table entries
    EVT_CHOICE( ID_APPLICATION_PREFERENCES_ENGINE, wxTTSSpeechSettingsPanel::OnApplicationPreferencesEngineSelected )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_ENGINE_PROGRAM_LOCATION, wxTTSSpeechSettingsPanel::OnApplicationPreferencesEngineProgramLocationUpdate )

    EVT_BUTTON( ID_APPLICATION_PREFERENCES_BROWSE_ENGINE_PROGRAM_LOCATION, wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEngineProgramLocationClick )
    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_BROWSE_ENGINE_PROGRAM_LOCATION, wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEngineProgramLocationUpdate )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_ENGINE_DATA_FOLDER, wxTTSSpeechSettingsPanel::OnApplicationPreferencesEngineDataFolderUpdate )

    EVT_BUTTON( ID_APPLICATION_PREFERENCES_BROWSE_ESPEAK_DATA_FOLDER, wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEspeakDataFolderClick )
    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_BROWSE_ESPEAK_DATA_FOLDER, wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEspeakDataFolderUpdate )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_ESPEAK_VOICE, wxTTSSpeechSettingsPanel::OnApplicationPreferencesEspeakVoiceUpdate )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_ESPEAK_VOICE_VARIANT, wxTTSSpeechSettingsPanel::OnApplicationPreferencesEspeakVoiceVariantUpdate )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_SPEECH_SPEED, wxTTSSpeechSettingsPanel::OnApplicationPreferencesSpeechSpeedUpdate )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_SPEECH_VOLUME, wxTTSSpeechSettingsPanel::OnApplicationPreferencesSpeechVolumeUpdate )

    EVT_UPDATE_UI( ID_APPLICATION_PREFERENCES_SPEECH_PITCH, wxTTSSpeechSettingsPanel::OnApplicationPreferencesSpeechPitchUpdate )

    EVT_BUTTON( ID_APPLICATION_PREFERENCES_TEST_SPEECH, wxTTSSpeechSettingsPanel::OnApplicationPreferencesTestSpeechClick )

    EVT_BUTTON( ID_APPLICATION_PREFERENCES_EDIT_PRONUNCIATIONS, wxTTSSpeechSettingsPanel::OnApplicationPreferencesEditPronunciationsClick )

    EVT_BUTTON( ID_APPLICATION_PREFERENCES_RESET_SPEECH_SETTINGS, wxTTSSpeechSettingsPanel::OnApplicationPreferencesResetSpeechSettingsClick )

////@end wxTTSSpeechSettingsPanel event table entries

END_EVENT_TABLE()

bool wxTTSSpeechSettingsPanel::m_showToolTips = true;

/*
 * wxTTSSpeechSettingsPanel constructors
 */

wxTTSSpeechSettingsPanel::wxTTSSpeechSettingsPanel()
{
    Init();
}

wxTTSSpeechSettingsPanel::wxTTSSpeechSettingsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
    Init();
    Create(parent, id, pos, size, style);
}


/*
 * wxTTSSpeechSettingsPanel creator
 */

bool wxTTSSpeechSettingsPanel::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
////@begin wxTTSSpeechSettingsPanel creation
    wxPanel::Create( parent, id, pos, size, style );

    CreateControls();
    if (GetSizer())
    {
        GetSizer()->SetSizeHints(this);
    }
    Centre();
////@end wxTTSSpeechSettingsPanel creation
    return true;
}


/*
 * wxTTSSpeechSettingsPanel destructor
 */

wxTTSSpeechSettingsPanel::~wxTTSSpeechSettingsPanel()
{
////@begin wxTTSSpeechSettingsPanel destruction
////@end wxTTSSpeechSettingsPanel destruction
}


/*
 * Member initialisation
 */

void wxTTSSpeechSettingsPanel::Init()
{
    m_ignoreEvents = false;

////@begin wxTTSSpeechSettingsPanel member initialisation
    m_innerSizer = NULL;
    m_speechEngineCtrl = NULL;
    m_urlCtrl = NULL;
    m_engineProgramLocation = NULL;
    m_engineDataFolder = NULL;
    m_speechVoice = NULL;
    m_speechVoiceVariant = NULL;
    m_speechSpeed = NULL;
    m_speechVolume = NULL;
    m_speechPitch = NULL;
    m_speechTestText = NULL;
    m_buttonGroupSizer = NULL;
    m_testSpeechCtrl = NULL;
    m_editCustomPronunciationsCtrl = NULL;
    m_resetSpeechSettingsCtrl = NULL;
////@end wxTTSSpeechSettingsPanel member initialisation
}


/*
 * Control creation for wxTTSSpeechSettingsPanel
 */

void wxTTSSpeechSettingsPanel::CreateControls()
{    
////@begin wxTTSSpeechSettingsPanel content construction
    wxTTSSpeechSettingsPanel* itemPanel1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemPanel1->SetSizer(itemBoxSizer2);

    m_innerSizer = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer2->Add(m_innerSizer, 1, wxGROW, 5);

    wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
    m_innerSizer->Add(itemBoxSizer4, 0, wxGROW, 5);

    wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer4->Add(itemBoxSizer5, 0, wxALIGN_CENTER_VERTICAL, 5);

    wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("Speech &engine:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxArrayString m_speechEngineCtrlStrings;
    m_speechEngineCtrl = new wxChoice( itemPanel1, ID_APPLICATION_PREFERENCES_ENGINE, wxDefaultPosition, wxSize(180, -1), m_speechEngineCtrlStrings, 0 );
    m_speechEngineCtrl->SetHelpText(_("The speech engine to use."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechEngineCtrl->SetToolTip(_("The speech engine to use."));
    itemBoxSizer5->Add(m_speechEngineCtrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    itemBoxSizer4->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_urlCtrl = new wxHyperlinkCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_GET_ESPEAK, _("Speech engine web site"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
    itemBoxSizer4->Add(m_urlCtrl, 0, wxALIGN_BOTTOM|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    m_innerSizer->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5);

    wxStaticText* itemStaticText11 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Program location:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_innerSizer->Add(itemStaticText11, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL);
    m_innerSizer->Add(itemBoxSizer12, 0, wxGROW, 5);

    m_engineProgramLocation = new wxTextCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_ENGINE_PROGRAM_LOCATION, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
    m_engineProgramLocation->SetHelpText(_("The full executable path for the current speech engine."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_engineProgramLocation->SetToolTip(_("The full executable path for the current speech engine."));
    itemBoxSizer12->Add(m_engineProgramLocation, 1, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5);

    wxButton* itemButton14 = new wxButton( itemPanel1, ID_APPLICATION_PREFERENCES_BROWSE_ENGINE_PROGRAM_LOCATION, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton14->SetHelpText(_("Click to browse for the executable."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        itemButton14->SetToolTip(_("Click to browse for the executable."));
    itemBoxSizer12->Add(itemButton14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_innerSizer->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5);

    wxStaticText* itemStaticText16 = new wxStaticText( itemPanel1, wxID_STATIC, _("Voices &folder:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_innerSizer->Add(itemStaticText16, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer17 = new wxBoxSizer(wxHORIZONTAL);
    m_innerSizer->Add(itemBoxSizer17, 0, wxGROW, 5);

    m_engineDataFolder = new wxTextCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_ENGINE_DATA_FOLDER, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
    m_engineDataFolder->SetHelpText(_("The speech engine voices folder (if applicable)."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_engineDataFolder->SetToolTip(_("The speech engine voices folder (if applicable)."));
    itemBoxSizer17->Add(m_engineDataFolder, 1, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5);

    wxButton* itemButton19 = new wxButton( itemPanel1, ID_APPLICATION_PREFERENCES_BROWSE_ESPEAK_DATA_FOLDER, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton19->SetHelpText(_("Click to browse for the voices folder."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        itemButton19->SetToolTip(_("Click to browse for the voices folder."));
    itemBoxSizer17->Add(itemButton19, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_innerSizer->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5);

    wxFlexGridSizer* itemFlexGridSizer21 = new wxFlexGridSizer(2, 2, 0, 0);
    itemFlexGridSizer21->AddGrowableCol(0);
    itemFlexGridSizer21->AddGrowableCol(1);
    m_innerSizer->Add(itemFlexGridSizer21, 0, wxGROW, 5);

    wxBoxSizer* itemBoxSizer22 = new wxBoxSizer(wxVERTICAL);
    itemFlexGridSizer21->Add(itemBoxSizer22, 0, wxGROW|wxGROW, 5);

    wxStaticText* itemStaticText23 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Voice:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer22->Add(itemStaticText23, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxArrayString m_speechVoiceStrings;
    m_speechVoice = new wxComboBox( itemPanel1, ID_APPLICATION_PREFERENCES_ESPEAK_VOICE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_speechVoiceStrings, wxCB_DROPDOWN );
    m_speechVoice->SetHelpText(_("The voice to use."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechVoice->SetToolTip(_("The voice to use."));
    itemBoxSizer22->Add(m_speechVoice, 0, wxGROW|wxALL, 5);

    wxBoxSizer* itemBoxSizer25 = new wxBoxSizer(wxVERTICAL);
    itemFlexGridSizer21->Add(itemBoxSizer25, 0, wxGROW|wxGROW, 5);

    wxStaticText* itemStaticText26 = new wxStaticText( itemPanel1, wxID_STATIC, _("V&oice variant:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer25->Add(itemStaticText26, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxArrayString m_speechVoiceVariantStrings;
    m_speechVoiceVariant = new wxComboBox( itemPanel1, ID_APPLICATION_PREFERENCES_ESPEAK_VOICE_VARIANT, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_speechVoiceVariantStrings, wxCB_READONLY );
    m_speechVoiceVariant->SetHelpText(_("The voice variant."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechVoiceVariant->SetToolTip(_("The voice variant."));
    itemBoxSizer25->Add(m_speechVoiceVariant, 0, wxGROW|wxALL, 5);

    m_innerSizer->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5);

    wxBoxSizer* itemBoxSizer29 = new wxBoxSizer(wxHORIZONTAL);
    m_innerSizer->Add(itemBoxSizer29, 0, wxGROW, 5);

    wxStaticText* itemStaticText30 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Speed:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer29->Add(itemStaticText30, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_speechSpeed = new wxSpinCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_SPEECH_SPEED, _T("50"), wxDefaultPosition, wxSize(65, -1), wxSP_ARROW_KEYS, 0, 100, 50 );
    m_speechSpeed->SetHelpText(_("The voice speed."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechSpeed->SetToolTip(_("The voice speed."));
    itemBoxSizer29->Add(m_speechSpeed, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText32 = new wxStaticText( itemPanel1, wxID_STATIC, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer29->Add(itemStaticText32, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 2);

    itemBoxSizer29->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL, 5);

    wxStaticText* itemStaticText34 = new wxStaticText( itemPanel1, wxID_STATIC, _("Vol&ume:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer29->Add(itemStaticText34, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_speechVolume = new wxSpinCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_SPEECH_VOLUME, _T("50"), wxDefaultPosition, wxSize(65, -1), wxSP_ARROW_KEYS, 0, 100, 50 );
    m_speechVolume->SetHelpText(_("The voice volume."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechVolume->SetToolTip(_("The voice volume."));
    itemBoxSizer29->Add(m_speechVolume, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText36 = new wxStaticText( itemPanel1, wxID_STATIC, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer29->Add(itemStaticText36, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 2);

    itemBoxSizer29->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL, 5);

    wxStaticText* itemStaticText38 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Pitch:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer29->Add(itemStaticText38, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_speechPitch = new wxSpinCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_SPEECH_PITCH, _T("50"), wxDefaultPosition, wxSize(65, -1), wxSP_ARROW_KEYS, -1, 100, 50 );
    m_speechPitch->SetHelpText(_("The voice pitch."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechPitch->SetToolTip(_("The voice pitch."));
    itemBoxSizer29->Add(m_speechPitch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText40 = new wxStaticText( itemPanel1, wxID_STATIC, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer29->Add(itemStaticText40, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 2);

    wxStaticText* itemStaticText41 = new wxStaticText( itemPanel1, wxID_STATIC, _("Test &text:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_innerSizer->Add(itemStaticText41, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer42 = new wxBoxSizer(wxHORIZONTAL);
    m_innerSizer->Add(itemBoxSizer42, 0, wxGROW, 5);

    wxBoxSizer* itemBoxSizer43 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer42->Add(itemBoxSizer43, 1, wxGROW, 5);

    m_speechTestText = new wxTextCtrl( itemPanel1, ID_APPLICATION_PREFERENCES_SPEECH_TEST_TEXT, wxEmptyString, wxDefaultPosition, wxSize(-1, 50), wxTE_MULTILINE );
    m_speechTestText->SetHelpText(_("Type test text here."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_speechTestText->SetToolTip(_("Type test text here."));
    itemBoxSizer43->Add(m_speechTestText, 1, wxGROW|wxALL, 5);

    m_buttonGroupSizer = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer42->Add(m_buttonGroupSizer, 0, wxALIGN_CENTER_VERTICAL, 5);

    m_testSpeechCtrl = new wxButton( itemPanel1, ID_APPLICATION_PREFERENCES_TEST_SPEECH, _("Test Te&xt to Speech"), wxDefaultPosition, wxDefaultSize, 0 );
    m_testSpeechCtrl->SetHelpText(_("Click to test speech settings."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_testSpeechCtrl->SetToolTip(_("Click to test speech settings."));
    m_buttonGroupSizer->Add(m_testSpeechCtrl, 0, wxGROW|wxALL, 5);

    m_editCustomPronunciationsCtrl = new wxButton( itemPanel1, ID_APPLICATION_PREFERENCES_EDIT_PRONUNCIATIONS, _("Edit &Custom Pronunciations"), wxDefaultPosition, wxDefaultSize, 0 );
    m_editCustomPronunciationsCtrl->SetHelpText(_("Click to define replacements for difficult words."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_editCustomPronunciationsCtrl->SetToolTip(_("Click to define replacements for difficult words."));
    m_buttonGroupSizer->Add(m_editCustomPronunciationsCtrl, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    m_resetSpeechSettingsCtrl = new wxButton( itemPanel1, ID_APPLICATION_PREFERENCES_RESET_SPEECH_SETTINGS, _("&Reset Speech Settings"), wxDefaultPosition, wxDefaultSize, 0 );
    m_resetSpeechSettingsCtrl->SetHelpText(_("Click to reset speech settings to the defaults."));
    if (wxTTSSpeechSettingsPanel::ShowToolTips())
        m_resetSpeechSettingsCtrl->SetToolTip(_("Click to reset speech settings to the defaults."));
    m_buttonGroupSizer->Add(m_resetSpeechSettingsCtrl, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    // Set validators
    m_speechSpeed->SetValidator( wxGenericValidator(& m_info.m_speed) );
    m_speechVolume->SetValidator( wxGenericValidator(& m_info.m_volume) );
    m_speechPitch->SetValidator( wxGenericValidator(& m_info.m_pitch) );
    m_speechTestText->SetValidator( wxGenericValidator(& m_info.m_testText) );
////@end wxTTSSpeechSettingsPanel content construction

    ApplyInfo(m_info);
}

/// Apply information. This is called in CreateControls or by SetInfo;
/// SetInfo should be called before TransferDataToWindow takes place.
void wxTTSSpeechSettingsPanel::ApplyInfo(wxTTSSpeechSettingsInfo& info)
{
    wxArrayString engineIds;
    if (info.m_speech)
        engineIds = info.m_speech->GetEngineIds();

    m_ignoreEvents = true;

    m_speechEngineCtrl->Clear();
    m_speechEngineCtrl->Append(engineIds);

    if (engineIds.Index(info.m_engine) == wxNOT_FOUND && engineIds.GetCount() > 0)
        info.m_engine = engineIds[0];

    if (!info.m_engine.IsEmpty())
        m_speechEngineCtrl->SetStringSelection(info.m_engine);

    m_ignoreEvents = false;
}


/*
 * Should we show tooltips?
 */

bool wxTTSSpeechSettingsPanel::ShowToolTips()
{
    return GetShowToolTips();
}

/*
 * Get bitmap resources
 */

wxBitmap wxTTSSpeechSettingsPanel::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin wxTTSSpeechSettingsPanel bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end wxTTSSpeechSettingsPanel bitmap retrieval
}

/*
 * Get icon resources
 */

wxIcon wxTTSSpeechSettingsPanel::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin wxTTSSpeechSettingsPanel icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end wxTTSSpeechSettingsPanel icon retrieval
}

/// Data transfer
bool wxTTSSpeechSettingsPanel::TransferDataToWindow()
{
    wxPanel::TransferDataToWindow();

    wxASSERT(m_info.m_speech != NULL);

    if (!m_info.m_speech)
        return false;

#ifdef __UNIX__
    if (m_info.m_speech->HasCapability(wxTTS_CAP_DATA_LOCATION))
    {
        wxString dataLocation = m_info.m_speech->GetDataLocation();
        if (dataLocation.IsEmpty())
        {
            if (!wxGetHomeDir().IsEmpty() && wxDirExists(wxGetHomeDir() + wxFILE_SEP_PATH + wxT("voice-data")))
                dataLocation = wxGetHomeDir() + wxFILE_SEP_PATH + wxT("voice-data");
            else if (wxDirExists(wxT("/usr/share/voice-data")))
                dataLocation = wxT("/usr/share/voice-data");

            if (!dataLocation.IsEmpty())
                m_info.m_speech->SetDataLocation(dataLocation);
        }
    }
#endif

    wxArrayString voices = m_info.m_speech->GetAvailableVoices();
    m_speechVoice->Clear();

    if (voices.GetCount() > 0)
        m_speechVoice->Append(voices);

    wxString v = m_info.m_speech->GetVoice();
    if (!v.IsEmpty())
    {
        if (m_speechVoice->FindString(v) != wxNOT_FOUND)
            m_speechVoice->SetStringSelection(v);
        else
            m_speechVoice->SetValue(v);
    }

    wxArrayString variantChoices = m_info.m_speech->GetAvailableVoiceVariants();
    m_speechVoiceVariant->Clear();
    if (variantChoices.GetCount() > 0)
    {
        m_speechVoiceVariant->Append(variantChoices);
        wxString voiceVariant = m_info.m_speech->GetVoiceVariant();
        int idx = variantChoices.Index(voiceVariant);
        if (idx != -1)
            m_speechVoiceVariant->SetSelection(idx);
    }

    m_engineProgramLocation->SetValue(m_info.m_speech->GetProgramLocation());
    m_engineDataFolder->SetValue(m_info.m_speech->GetDataLocation());

    wxString url(m_info.m_speech->GetPropertyString(wxTTS_PROP_ENGINE_WEBSITE));
    if (!url.IsEmpty())
    {
        m_urlCtrl->SetURL(url);
        m_urlCtrl->Show(true);
    }
    else
        m_urlCtrl->Show(false);

    return true;
}

bool wxTTSSpeechSettingsPanel::TransferDataFromWindow()
{
    wxPanel::TransferDataFromWindow();

    wxASSERT(m_info.m_speech != NULL);

    if (!m_info.m_speech)
        return false;

    if (m_speechVoiceVariant->GetSelection() != -1)
    {
        wxArrayString variantChoices = m_info.m_speech->GetAvailableVoiceVariants();
        int idx = m_speechVoiceVariant->GetSelection();
        if (idx != -1 && ((size_t) idx < variantChoices.GetCount()))
        {
            wxString s = variantChoices[idx];
            m_info.m_speech->SetVoiceVariant(s);
        }
    }
    
    m_info.m_speech->SetProgramLocation(m_engineProgramLocation->GetValue());
    m_info.m_speech->SetDataLocation(m_engineDataFolder->GetValue());
    m_info.m_speech->SetVoice(m_speechVoice->GetValue());
    m_info.m_speech->SetVoiceVariant(m_speechVoiceVariant->GetValue());
    m_info.m_speech->SetSpeed(m_info.m_speed, wxTTS_PERCENT);
    m_info.m_speech->SetVolume(m_info.m_volume, wxTTS_PERCENT);
    m_info.m_speech->SetPitch(m_info.m_pitch, wxTTS_PERCENT);

    return true;
}

/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_PROGRAM_LOCATION
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesEngineProgramLocationUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_PROGRAM_LOCATION));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_BROWSE_ESPEAK_PROGRAM_LOCATION
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEngineProgramLocationUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_PROGRAM_LOCATION));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_DATA_FOLDER
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesEngineDataFolderUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_DATA_LOCATION));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_BROWSE_ESPEAK_DATA_FOLDER
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEspeakDataFolderUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_DATA_LOCATION));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_VOICE_VARIANT
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesEspeakVoiceVariantUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_VOICE_VARIATIONS));
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_APPLICATION_PREFERENCES_BROWSE_ENGINE_PROGRAM_LOCATION
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEngineProgramLocationClick( wxCommandEvent& WXUNUSED(event) )
{
    if (!m_info.m_speech)
        return;

    wxTextCtrl* textCtrl = m_engineProgramLocation;
    
    wxString msg = _("Choose a command");
    wxWindow* parent = wxGetTopLevelParent(this);
    wxString filename(textCtrl->GetValue());

    wxString file(wxFileNameFromPath(filename));
    wxString path(wxPathOnly(filename));
    wxString wildcard(wxT("*.*"));

    wxFileDialog fileDlg(parent, msg, path, file, wildcard);
    if (fileDlg.ShowModal() == wxID_OK)
    {
        path = fileDlg.GetPath();

        textCtrl->SetValue(path);

        wxString oldDataLocation = m_info.m_speech->GetDataLocation();

        m_info.m_speech->SetProgramLocation(path);

        wxString newDataLocation = m_info.m_speech->GetDataLocation();

        // Setting the program location may have caused the data location
        // to be guessed, and therefore the voices list to become available.
        // If so, set the new data location value and update the available voices. 

        if (oldDataLocation != newDataLocation && wxDirExists(newDataLocation))
        {
            wxArrayString voices = m_info.m_speech->GetAvailableVoices();
            
            wxString sel(m_speechVoice->GetValue());
            
            m_speechVoice->Clear();
            m_speechVoice->Append(voices);
            
            m_speechVoice->SetValue(sel);
        }
    }
}

/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_APPLICATION_PREFERENCES_BROWSE_ESPEAK_DATA_FOLDER
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesBrowseEspeakDataFolderClick( wxCommandEvent& WXUNUSED(event) )
{
    if (!m_info.m_speech)
        return;

    wxTextCtrl* textCtrl = m_engineDataFolder;
    wxString msg = _("Select the voice data folder");
    wxWindow* parent = wxGetTopLevelParent(this);

    wxDirDialog dirDlg(wxGetTopLevelParent(parent), msg, textCtrl->GetValue(), wxDD_DEFAULT_STYLE);
    if (dirDlg.ShowModal() == wxID_OK)
    {
        textCtrl->SetValue(dirDlg.GetPath());

        {
            m_info.m_speech->SetProperty(wxTTS_PROP_DATA_LOCATION, dirDlg.GetPath());
            wxArrayString voices = m_info.m_speech->GetAvailableVoices();
            wxString sel(m_speechVoice->GetValue());

            m_speechVoice->Clear();
            m_speechVoice->Append(voices);

            m_speechVoice->SetValue(sel);
        }
    }
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_APPLICATION_PREFERENCES_TEST_SPEECH
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesTestSpeechClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();
   
    if (m_info.m_speech)
        m_info.m_speech->Speak(m_speechTestText->GetValue());
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_APPLICATION_PREFERENCES_EDIT_PRONUNCIATIONS
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesEditPronunciationsClick( wxCommandEvent& WXUNUSED(event) )
{
    wxASSERT(m_info.m_speech->GetTransformer() != NULL);
    if (!m_info.m_speech->GetTransformer())
        return;
    TransferDataFromWindow();

    // TODO: how to pass HTML description
    wxTTSCustomPronunciationDialog dialog;
    dialog.SetSpeech(m_info.m_speech);
    dialog.Create(m_info.m_speech->GetTransformer(), wxGetTopLevelParent(this));
    dialog.ShowModal();

    // wxGetApp().SavePronunciationTable();
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_APPLICATION_PREFERENCES_RESET_SPEECH_SETTINGS
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesResetSpeechSettingsClick( wxCommandEvent& WXUNUSED(event) )
{
    TransferDataFromWindow();

    if (m_info.m_speech)
    {
        m_info.m_speech->SetVoice(m_info.m_speech->GetDefaultVoice());
        m_info.m_speech->SetVoiceVariant(m_info.m_speech->GetDefaultVoiceVariant());
        m_info.m_testText = wxT("Testing the text to speech settings.");
        m_info.m_speed = wxTTS_SPEED_DEFAULT_PERCENT;
        m_info.m_volume = wxTTS_VOLUME_DEFAULT_PERCENT;
        m_info.m_pitch = wxTTS_PITCH_DEFAULT_PERCENT;
    }

    TransferDataToWindow();
}


/*
 * wxEVT_COMMAND_CHOICE_SELECTED event handler for ID_APPLICATION_PREFERENCES_ENGINE
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesEngineSelected( wxCommandEvent& event )
{
    if (m_ignoreEvents)
        return;
        
    TransferDataFromWindow();

    m_ignoreEvents = true;
    
    if (m_info.m_speech)
    {
        wxString oldEngine = m_info.m_speech->GetEngine();

        if (m_info.m_speech->SetEngine(event.GetString()))
        {
            m_info.m_engine = event.GetString();
        }
        else
        {
            m_speechEngineCtrl->SetStringSelection(oldEngine);
        }
    }
    
    TransferDataToWindow();

    m_ignoreEvents = false;    
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_VOICE
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesEspeakVoiceUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_VOICE));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_SPEED
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesSpeechSpeedUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_SPEED));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_VOLUME
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesSpeechVolumeUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_VOLUME));
}


/*
 * wxEVT_UPDATE_UI event handler for ID_APPLICATION_PREFERENCES_ESPEAK_PITCH
 */

void wxTTSSpeechSettingsPanel::OnApplicationPreferencesSpeechPitchUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_info.m_speech && m_info.m_speech->HasCapability(wxTTS_CAP_PITCH));
}

